﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; 

using System.Data.Entity;
using System.Data;
using System.Data.Objects;
using System.Data.Objects.DataClasses;

namespace EngineLayer.Model
{
   
    using DBLayer;
    public abstract class DBEntities
    {
        protected readonly static Entities database = new Entities();
   
        public bool SaveChanges()
        {
            try
            {
                database.SaveChanges();
            }
            catch (System.Data.UpdateException)
            {
            //    if (OnDbError != null)
       //         {
   //                 ErroEventArgs e = new ErroEventArgs(MessageError.FillDataRequired, 0, MessageBoxButtons.OK, MessageBoxIcon.Information);
    //                OnDbError(this, e);
                    return false;
              //  }
            }
            catch
            {
                //if (OnDbError != null)
                //{
                //    ErroEventArgs e = new ErroEventArgs(MessageError.UnnexpectedErrorDb, 0, MessageBoxButtons.OK, MessageBoxIcon.Error);
                //    OnDbError(this, e);
                    return false;
                //}
            }

            return true;
        }
       
        public object DataSource { get; set; }
       
        public IEnumerable<object> GetValues
        {
            get { return (IEnumerable<object>)DataSource; }
        }

        public void UndoChanges<T>(ObjectSet<T> data) where T : EntityObject
        {
            IEnumerable<T> undo = data.AsEnumerable().Where(h => h.EntityState == EntityState.Modified || h.EntityState == EntityState.Deleted);
            processUndo<T>(undo);
        }

        public void UndoChanges<T1, T2>(ObjectSet<T2> data)
            where T1 : EntityObject
            where T2 : EntityObject
        {
            IEnumerable<T1> undo = data.OfType<T1>().AsEnumerable().Where(h => h.EntityState == EntityState.Modified || h.EntityState == EntityState.Deleted);
            processUndo<T1>(undo);
        }

        private void processUndo<T>(IEnumerable<T> undo)
        {
            database.Refresh(RefreshMode.StoreWins, undo);

            undo = (from e in database.ObjectStateManager.GetObjectStateEntries(EntityState.Added) select e.Entity).ToList().OfType<T>();
            foreach (T entity in undo)
            {
                database.Detach(entity);
            }
        }

        public bool isEdited<T>(ObjectSet<T> data) where T : EntityObject
        {
            return (
                       data.AsEnumerable().Where(h => (h.EntityState == EntityState.Deleted) || (h.EntityState == EntityState.Modified)).Count() +
                       database.ObjectStateManager.GetObjectStateEntries(EntityState.Added).Select(n => n.Entity).Count()
                       > 0
                    );

        }
    
        public bool isEdited<T1, T2>(ObjectSet<T2> data)
            where T1 : EntityObject
            where T2 : EntityObject
        {
            return (
                    data.OfType<T1>().AsEnumerable().Where(h => h.EntityState == EntityState.Modified || h.EntityState == EntityState.Deleted).Count() +
                    database.ObjectStateManager.GetObjectStateEntries(EntityState.Added).Select(n => n.Entity).Count()
                    > 0
                    );
        }
    }
}
